﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Processing;
using Cloo;
using Processing.Structures;

namespace RayTracer.Kernels
{
    /// <summary>
    /// Farbkonvertierung: Wandelt  die Fließkommafarben in
    /// Bytefarben um und korrigiert dabei den Gammawert.
    /// </summary>
    partial class KernelConvertColor : AKernel
    {
        #region Attribute
        #region GPU
        private Buffer<Float4> gpu_fcolor;

        private Buffer<Byte4> gpu_bcolor;
        #endregion GPU
        #endregion Attribute

        #region Eigenschaften
        #region Dateninitialisierung
        /// <summary>
        /// Gibt und setzt die Fließkommafarben.
        /// </summary>
        public Buffer<Float4> FloatingColors { get { return gpu_fcolor; } set { gpu_fcolor = value; } }

        /// <summary>
        /// Gibt die Ergebnisfarben an.
        /// </summary>
        public Buffer<Byte4> ResultColors
        {
            get
            {
                if (State != KernelState.Done) throw new Exception("Die Kernel wurde noch nicht berechnet.");
                return gpu_bcolor;
            }
        }
        #endregion Dateninitialisierung

        #region Kernelausführung
        /// <summary>
        /// Gibt den Quellcode des Programms an.
        /// </summary>
        protected override string ProgramSource { get { return KERNEL_SOURCE; } }

        /// <summary>
        /// Gibt den Namen des Programms an.
        /// </summary>
        protected override string ProgramName { get { return KERNEL_MAIN; } }

        /// <summary>
        /// Gibt die Dimension des Programms an.
        /// </summary>
        protected override long[] Dimensions { get { return new long[] { gpu_fcolor.Length }; } }

        /// <summary>
        /// Gibt an ob die Kerneldaten valid initialisiert sind.
        /// </summary>
        protected override bool IsValidInitialized
        {
            get
            {
                if (gpu_fcolor == null) throw new RayTracerException("Die Fließkommafarben müssen angegeben werden.");
                return
                    gpu_fcolor.Length > 0;
            }
        }
        #endregion Kernelausführung

        /// <summary>
        /// Gibt eine hochgegriffene Schätzung über die Anzahl der Bytes pro Pixel/Ray.
        /// </summary>
        public static int BytesPerPixel { get { return (8 * (sizeof(float) * 4)) + (sizeof(float) * 8); } }
        #endregion Eigenschaften

        #region Methoden
        /// <summary>
        /// Instanziiert und initialisiert die Kernel.
        /// </summary>
        /// <param name="processor">Der Prozessor.</param>
        public KernelConvertColor(Processor processor) : base(processor) { }

        /// <summary>
        /// Führt Aktionen vor der Ausführung der Kernel - mit dem Run-Aufruf aus. (z. B. Datentransport von CPU zu GPU)
        /// </summary>
        protected override void PrepareKernelExecution()
        {
            base.PrepareKernelExecution();
            gpu_bcolor = Processor.AllocateBuffer<Byte4>(gpu_fcolor.Length);
        }

        /// <summary>
        /// Setzt die Daten in Kernelargumente fest.
        /// </summary>
        protected override void SetArguments()
        {
            SetArgument(0, gpu_fcolor);

            SetArgument(1, gpu_bcolor, true);
        }
        #endregion Methoden
    }
}
